define(
["./PickRenderSyst", "./PickUnit", "framework/graphic/WebGL"],
function(PickRenderSyst, PickUnit, WebGL){
    return {
        create: function() {
            var _system = null;
            var _pickUnits = [];
            var _colorCode = [0,0,1];
            var _tempPixel = new Uint8Array(4);
            var _enable = true;

            function _incColorCode() {
                var increment = 1;
                _colorCode[2] += increment;
                if(_colorCode[2] > 255) {
                    _colorCode[2] = 0;
                    _colorCode[1] += increment;
                    if(_colorCode[1] > 255) {
                        _colorCode[1] = 0;
                        _colorCode[0] += increment;
                        if(_colorCode[0] > 255) {
                            _colorCode[0] = 0;
                            throw "Color code run out!";
                        }
                    }
                }

                return _colorCode;
            }

            function _colorToId(color) {
                return color[0] + color[1] * 256 + color[2] * 256 * 256;
            }

            function _colorMap255to1(color) {
                return color.map(function(val){return val/255;});
            }

            var _self = {
                //The buffers
                posBuf: null,
                colorBuf: null,
                indicesBuf: null,
                visibleBuf: null,

                //Drawing configurations
                itemsToDraw: 0,
                offsetToDraw: 0,

                fetchColorUnit: function() {
                    var color = _incColorCode();
                    var id = _colorToId(color);

                    var unit = PickUnit.create(_colorMap255to1(color), id);

                    _pickUnits[id] = unit;

                    return unit;
                },

                init: function(systemMgr, posBuf, colorBuf, indicesBuf, visibleBuf) {
                    //Get and register myself to the system
                    _system = systemMgr.getSystem(PickRenderSyst);
                    _system.add(_self);

                    //Assign buffers
                    _self.posBuf = posBuf;
                    _self.colorBuf = colorBuf;
                    _self.indicesBuf = indicesBuf;
                    _self.visibleBuf = visibleBuf;

                    //Reset drawing configuration
                    _self.toDefaultConf();

                    return this;
                },

                destroy: function() {
                    //Unregister myself from the system
                    _system.rem(_self);
                },

                /**
                 * Set the drawing configuration to default (draw all)
                 */
                toDefaultConf: function() {
                    _self.itemsToDraw = _self.indicesBuf.numItems;
                    _self.offsetToDraw= 0;
                },

                /**
                 * Call this to draw to the screen
                 */
                render: function(shader) {
                    //Check enabled
                    if(!_enable) return;

                    //Assign the buffers
                    WebGL.pointAttrib(shader.getAttribute("aPos"), _self.posBuf);
                    WebGL.pointAttrib(shader.getAttribute("aColor"), _self.colorBuf);
                    WebGL.pointAttrib(shader.getAttribute("aVisible"), _self.visibleBuf);

                    //Clear screen
                    var gl = WebGL.gl;
                    gl.clear(gl.COLOR_BUFFER_BIT);

                    //Draw call
                    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _self.indicesBuf);
                    gl.drawElements(gl.TRIANGLES, _self.itemsToDraw, gl.UNSIGNED_SHORT, _self.offsetToDraw);
                },

                getPickedUnit: function(x, y) {
                    //Check enabled
                    if(!_enable) return null;

                    //Get color
                    var color = _tempPixel;
                    WebGL.gl.readPixels(
                        x, y,
                        1, 1,
                        WebGL.gl.RGBA, WebGL.gl.UNSIGNED_BYTE, color
                    );

                    //Translate to id
                    var id = _colorToId(color);

                    //Get pick unit
                    return _pickUnits[id];
                },

                setEnable: function(val) {
                    _enable = val;
                }
            };

            return _self;
        }
    }
});